/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package plash.display;

import plash.events.KeyEvent;
import processing.event.MouseEvent;

/**
 *
 * @author #0K Srinivasan <hashok.com>
 */
public class InteractiveObject extends DisplayObject
{

    protected int __tabIndex = 0;
    protected boolean __keyEventsRegistered = false;
    protected boolean __mouseEventsRegistered = false;
    protected boolean __mouseInside = false;
    protected boolean __doubleClickEnabled = false;
    protected boolean __mouseEnabled = true;
    protected boolean __tabEnabled = true;
    protected boolean __rolledOver = false;

    public InteractiveObject()
    {
        super();
    }

    protected void __unregisterMouseEvents()
    {
        if (__mouseEventsRegistered)
        {
            if (__stage != null)
            {
                __stage.unregisterMethod("mouseEvent", this);
                __mouseEventsRegistered = false;
            }
        }
    }

    protected void __unregisterKeyEvents()
    {
        if (__keyEventsRegistered)
        {
            if (__stage != null)
            {
                __stage.unregisterMethod("keyEvent", this);
                __keyEventsRegistered = false;
            }
        }
    }

    protected void __registerMouseEvents()
    {
        if (__mouseEnabled)
        {
            if (!__mouseEventsRegistered)
            {
                if(__stage != null)
                {
                    __stage.registerMethod("mouseEvent", this);
                    __mouseEventsRegistered = true;
                }
            }
        }
    }

    protected void __registerKeyEvents()
    {
        if (!__keyEventsRegistered)
        {
            if (__stage != null)
            {
                __stage.registerMethod("keyEvent", this);
                __keyEventsRegistered = true;
            }
        }
    }

    public void mouseEvent(processing.event.MouseEvent me)
    {
        int actionId = me.getAction();
        int mx;
        int my;
        int clickCount;

        if (!__mouseEnabled)
        {
            return;
        }
        mx = my = 0;

        __mouseInside = false;

        if (this.getParent() != null)
        {
//            mx = me.getX() - this.getAbsoluteX();
//            my = me.getY() - this.getAbsoluteY();

            mx = me.getX() - this.getAbsoluteX();
            my = me.getY() - this.getAbsoluteY();

            __mouseX = mx;
            __mouseY = my;

            __mouseInside = this.getBoundingBox().containsPoint((int)(me.getX() * this.__scaleX), (int)(me.getY() * this.__scaleY));
//            __mouseInside = this.__boundingBox.containsPoint((int)(me.getX()), (int)(me.getY()));
        }


        if (!__mouseInside)
        {
            if (__rolledOver)
            {
                dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_OUT, __mouseX, __mouseY));
                __rolledOver = false;
            }
            return;
        }

        switch (actionId)
        {
            case MouseEvent.PRESSED:
                dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_DOWN, mx, my));
                break;
            case MouseEvent.CLICKED:
                clickCount = me.getClickCount();
                if (clickCount == 2)
                {
                    if (__doubleClickEnabled)
                    {
                        dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.DOUBLE_CLICK, mx, my));
                    }
                }
                else if (clickCount == 1)
                {
                    dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.CLICK, mx, my));
                }
                break;
            case MouseEvent.RELEASED:
                dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_UP, mx, my));
                break;
            case MouseEvent.MOVED:
                dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_MOVE, mx, my));
                break;
            case MouseEvent.DRAGGED:
                dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_DRAGGED, mx, my));
                break;
        }

        if (!__rolledOver)
        {
            dispatchEvent(new plash.events.MouseEvent(plash.events.MouseEvent.MOUSE_OVER, __mouseX, __mouseY));
            __rolledOver = true;
        }
    }

    public void keyEvent(processing.event.KeyEvent ke)
    {
        int actionId = ke.getAction();

        switch (actionId)
        {
            case processing.event.KeyEvent.PRESSED:
                dispatchEvent(new KeyEvent(KeyEvent.KEY_DOWN,
                        ke.getKeyCode(),
                        ke.getKey(),
                        ke.isShiftDown(),
                        ke.isControlDown(),
                        ke.isAltDown()));
                break;
            case processing.event.KeyEvent.RELEASED:
                dispatchEvent(new KeyEvent(KeyEvent.KEY_UP,
                        ke.getKeyCode(),
                        ke.getKey(),
                        ke.isShiftDown(),
                        ke.isControlDown(),
                        ke.isAltDown()));
                break;
        }
    }

    @Override
    public void setStage(IStage stage)
    {
        __unregisterKeyEvents();
        __unregisterMouseEvents();

        super.setStage(stage);

        __registerKeyEvents();
        __registerMouseEvents();
    }

    public int getTabIndex()
    {
        return __tabIndex;
    }

    public void setTabIndex(int tabIndex)
    {
        this.__tabIndex = tabIndex;
    }

    public boolean isDoubleClickEnabled()
    {
        return __doubleClickEnabled;
    }

    public void setDoubleClickEnabled(boolean doubleClickEnabled)
    {
        this.__doubleClickEnabled = doubleClickEnabled;
    }

    public boolean isMouseEnabled()
    {
        return __mouseEnabled;
    }

    public void setMouseEnabled(boolean mouseEnabled)
    {
        this.__mouseEnabled = mouseEnabled;
        this.__registerMouseEvents();
    }

    public boolean isTabEnabled()
    {
        return __tabEnabled;
    }

    public void setTabEnabled(boolean tabEnabled)
    {
        this.__tabEnabled = tabEnabled;
    }
}
